﻿using System;
using System.IO;
using DKE_Kinect.Entwicklung.Core;
using Microsoft.Xna.Framework;

namespace DKE_Kinect.Entwicklung.Grafik.ControlManaging
{
	public class ProjectMenu : Control
	{
		#region Fields

		// Readonly - Fields
		private readonly int[] pOffsets = new int[] { 80, 171, 217, 240, 240, 217, 171, 80 };

		private int pElements;
		private int pRows, pColumns;
		private int pRowPos, pColPos;

		private Button[,] pButtons;
		private int pRowGap, pColumnGap;

        private String[] pFilenames;

		#endregion

        /// <summary>
        /// Erstellt das Projekt-Lade/Speicher-Menü
        /// </summary>
        /// <param name="Owner">ContainerManager</param>
        /// <param name="ProjectDir">Pfad zum Speichern/Laden von Projekten</param>
        /// <param name="Rows">Anzahl der Reihen</param>
		//public ProjectMenu (ContainerManager Owner, String ProjectDir, int Rows)#
        public ProjectMenu(ContainerManager Owner, int Rows)
			: base("ProjectMenu")
		{
			if (Owner == null)
				throw new ArgumentNullException();
			else if (Rows < 1)
				throw new ArgumentOutOfRangeException();

			this.Parent = Owner;

            // Projekt-Dateien initialisieren
           // pFilenames = getFiles(ProjectDir);
            pFilenames = SaveLoad.Projects;
			// Parameter übernehmen und Spalten errechnen:
			this.pElements = pFilenames.Length+1;
			this.pRows = Rows;

			float calcColumns = (float)this.pElements / Rows;
			if (this.pElements / Rows != calcColumns)
				calcColumns++;

			this.pColumns = (int)calcColumns;

			// Weitere Daten initialisieren:
			this.pRowPos = 0;
			this.pColPos = 0;

			// Abstände setzen:
			this.pRowGap = 5;
			this.pColumnGap = 5;

			// Buttons initialisieren:
			int elementCounter = 0;
			this.pButtons = new Button[this.pRows, this.pColumns];

			this.Location = new Point(0, 0);

			for (int row = 0; row < this.pRows; row++)
			{
				for (int column = 0; column < this.pColumns; column++)
				{
					if (elementCounter == this.pElements)
						break;

                    if (elementCounter == this.pElements-1)
                        this.pButtons[row, column] = new Button("NEW");
					else
                        this.pButtons[row, column] = new Button(pFilenames[elementCounter]);

					this.pButtons[row, column].Parent = this;
					this.pButtons[row, column].Visible = false;
                    this.pButtons[row, column].Text = this.pButtons[row, column].Name;
					this.pButtons[row, column].Layout = ControlManaging.Layout.Stretch;

					this.pButtons[row, column].Texture = ContainerRessources.GetButtons(ButtonType.PBubbleMenuStatic)[0];
					this.pButtons[row, column].HoverTexture = ContainerRessources.GetButtons(ButtonType.PBubbleMenuHover)[0];

					elementCounter++;
				}
			}

			this.Size = this.pParent.Size;

			//this.pTexture = ContentManager.loadContent<Texture2D>("textures/Color");
			this.pAlpha = 0.75f;
			this.Layout = ControlManaging.Layout.Stretch;
		}

		/// <summary>
		/// Springt zum nächsthöheren Element bzw. an das unterste, sofern bereits das oberste angewählt ist.
		/// </summary>
		public void Up ()
		{
			int buffer = this.pRowPos;

			this.pRowPos--;

			if (this.pRowPos < 0)
				this.pRowPos = this.pRows - 1;

			int elementPos = (this.pRowPos + 1) * (this.pColPos + 1);
			if (elementPos > this.pElements)
				this.pRowPos--;

			if (buffer != this.pRowPos)
			{
				this.pButtons[buffer, this.pColPos].ChangeHoverEffect();
				this.pButtons[this.pRowPos, this.pColPos].ChangeHoverEffect();
			}
		}

		/// <summary>
		/// Springt zum nächstniederen Element bzw. an das oberste, sofern bereits das unterste angewählt ist.
		/// </summary>
		public void Down ()
		{
			int buffer = this.pRowPos;

			this.pRowPos++;

			if (this.pRowPos >= this.pRows)
				this.pRowPos = 0;

			int elementPos = (this.pRowPos + 1) * (this.pColPos + 1);
			if (elementPos > this.pElements)
				this.pRowPos = 0;

			if (buffer != this.pRowPos)
			{
				this.pButtons[buffer, this.pColPos].ChangeHoverEffect();
				this.pButtons[this.pRowPos, this.pColPos].ChangeHoverEffect();
			}
		}

		/// <summary>
		/// Springt zum linken Nachbarn bzw. zum rechten aüßeren Nachbarn, sofern bereits der links äußere angewählt ist.
		/// </summary>
		public void Left ()
		{
			int buffer = this.pColPos;

			this.pColPos--;

			if (this.pColPos < 0)
				this.pColPos = this.pColumns - 1;

			int elementPos = (this.pRowPos + 1) * (this.pColPos + 1);
			if (elementPos > this.pElements)
				this.pColPos--;

			if (buffer != this.pColPos)
			{
				this.pButtons[this.pRowPos, buffer].ChangeHoverEffect();
				this.pButtons[this.pRowPos, this.pColPos].ChangeHoverEffect();
			}
		}

		/// <summary>
		/// Springt zum rechten Nachbarn bzw. zum linken aüßeren Nachbarn, sofern bereits der rechte äußere angewählt ist.
		/// </summary>
		public void Right ()
		{
			int buffer = this.pColPos;

			this.pColPos++;

			if (this.pColPos >= this.pColumns)
				this.pColPos = 0;

			int elementPos = (this.pRowPos + 1) * (this.pColPos + 1);
			if (elementPos > this.pElements)
				this.pColPos = 0;

			if (buffer != this.pColPos)
			{
				this.pButtons[this.pRowPos, buffer].ChangeHoverEffect();
				this.pButtons[this.pRowPos, this.pColPos].ChangeHoverEffect();
			}
		}

        /// <summary>
        /// Auswahl des Ladepunktes
        /// </summary>
		public void ChooseToLoad()
		{
            StateManager.ReturnToPrevState();

            if (this.pButtons[this.pRowPos, this.pColPos].Name == "NEW")
                Application.CurrentProjekt = new Projekt("NEW");
            else
                SaveLoad.LoadGameFile(this.pButtons[this.pRowPos, this.pColPos].Name);
		}

        /// <summary>
        /// Auswahl des Speicherpunktes
        /// </summary>
        public void ChooseToSave()
        {
            StateManager.ReturnToPrevState();

            if (this.pButtons[this.pRowPos, this.pColPos].Name == "NEW")
                SaveLoad.SaveGameFile(("P" + pElements).PadRight(3,'0'), Application.CurrentProjekt, Application.PolyvoxManager.VolumeRecord );
            else
               SaveLoad.SaveGameFile(this.pButtons[this.pRowPos, this.pColPos].Name, Application.CurrentProjekt, Application.PolyvoxManager.VolumeRecord );
        }

		private void calculateNewSizes ()
		{
			int offsetLeft, offsetTop;
			int newSize;
			if (this.pSize.X > this.pSize.Y)
			{
				offsetTop = 0;
				newSize = (this.pSize.Y - (this.pRows - 1) * this.pRowGap) / this.pRows;
				offsetLeft = (this.pSize.X - this.pColumns * newSize - (this.pColumns - 1) * this.pColumnGap) / 2;
			}
			else
			{
				offsetLeft = 0;
				newSize = (this.pSize.X - (this.pColumns - 1) * this.pColumnGap) / this.pColumns;
				offsetTop = (this.pSize.Y - this.pRows * newSize - (this.pRows - 1) * this.pRowGap) / 2;
			}

			int elementCounter = 0;

			for (int row = 0; row < this.pRows; row++)
				for (int column = 0; column < this.pColumns; column++)
				{
					if (elementCounter == this.pElements)
						break;

					this.pButtons[row, column].Bounds = new Rectangle(
						offsetLeft + column * (newSize + this.pColumnGap),
						offsetTop + row * (newSize + this.pRowGap),
						newSize, newSize);

					elementCounter++;
				}
		}

		protected override void OnPaint (PaintEventArgs e)
		{
			base.OnPaint(e);
		}

		/// <summary>
		/// Löst das Ereignis SizeChanged aus.
		/// </summary>
		/// <param name="e"></param>
		protected override void OnSizeChanged (EventArgs e)
		{
			this.calculateNewSizes();

			base.OnSizeChanged(e);
		}

		/// <summary>
		/// Löst das VisibleChanging - Ereignis aus. Beim überschreiben dieser Methode muss ebenfalls das Setzen der zugehörigen Eigenschaft Visible selbst vorgenommen werden sowie das damit verbundende OnVisibleChanged - Ereignis.
		/// </summary>
		/// <param name="e"></param>
		protected override void OnVisibleChanging (EventArgs e)
		{
			if (this.pVisible)
			{
				for (int row = 0; row < this.pButtons.GetLength(0); row++)
					for (int column = 0; column < this.pButtons.GetLength(1); column++)
					{
						if (this.pButtons[row, column] == null)
							break;
						this.pButtons[row, column].Visible = false;
					}
			}

			base.OnVisibleChanging(e);
		}

		/// <summary>
		/// Löst das Ergebnis VisibleChanged aus.
		/// </summary>
		/// <param name="e"></param>
		protected override void OnVisibleChanged (EventArgs e)
		{
			base.OnVisibleChanged(e);

			if (this.pVisible)
			{
				int elementCounter = 0;

				for (int row = 0; row < this.pButtons.GetLength(0); row++)
				{
					for (int column = 0; column < this.pButtons.GetLength(1); column++)
					{
						if (elementCounter == this.pElements)
							break;

						this.pButtons[row, column].Visible = true;
						elementCounter++;
					}
				}

				this.pButtons[this.pRowPos, this.pColPos].ActivateHoverEffect();
			}
		}

        private static String[] getFiles(String Dir)
        {
            String[] files = Directory.GetFiles(@Dir, "*.sav");
            for (int i = 0; i < files.Length; i++)
            {
                files[i] = Path.GetFileNameWithoutExtension(files[i]);
            }
               
            return files;
        }

		
	}
}
